#ifndef _MUNIX_Bus_H
#define	_MUNIX_Bus_H
/*******************************************************************************
 ** Name: bus.h                                                               **
 ** Description:              **
 **                                                                           **
 ** Open Source Initiative (OSI) Approved License                             **
 **                                                                           **
 ** The contents of this file are subject to the terms of the                 **
 ** Common Development and Distribution License, Version 1.0 only             **
 ** (the "License").  You may not use this file except in compliance          **
 ** with the License.                                                         **
 **                                                                           **
 ** You can find a copy of the license in the license.txt within              **
 ** this distribution or at http://www.munixos.net/licensing.                 **
 ** Software distributed under the License is distributed on an "AS IS"       **
 ** basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.           **
 ** See the License for the specific language governing permissions           **
 ** and limitations under the License.                                        **
 **                                                                           **
 ** When distributing Covered Code, include this CDDL header in each          **
 ** file and include the License file at $HOME/license.txt.                   **
 ** If applicable, add the following below this header, with the indicated    **
 ** fields enclosed by brackets "[]" replaced with your own identifying       **
 ** information: Portions Copyright [yyyy] [name of copyright owner]          **
 **                                                                           **
 **                                                                           **
 ** Copyright (c) 2009-2010  Barry Gian James <bjames@munixos.net>            **
 ** All rights reserved.                                                      **
 **                                                                           **
 ** Ref: $HeadURL$
 ******************************************************************************/
// Portions (C) 2011 OpenHouseware, LLC.
// All Rights Reserved

// $Id$
// Last Modified $DateTime$ by $Author$
#include "common.h"
#include "ioport.h"
#include "rbuff.h"

enum class Signal { Low, High };

enum class BusType { SPI, TWI, USART, USI, USB, Control, Address, Data, Short, Video };
enum class BusMode { Master, Slave };
class Bus
{
public:
    Bus(uint8 i, BusType t, BusMode m);
    Bus(const Bus& orig) = default;
    virtual ~Bus() { }

    // Bus device interface
    // The initialization method to connect to the Bus's bus
    virtual bool    Connect() = 0;
    // Send a byte to <remote> which could be TWI address or SPI ID for !CS
    virtual void    SendByte(uint8 remote, char byte) = 0;
    // Send a 16-bit word to <remote>.
    virtual void    SendWord(uint8 remote, wchar_t word) = 0;
    // Read a byte
    virtual char    RecvByte() = 0;
    virtual wchar_t RecvWord() = 0;
    virtual void    PowerUp() = 0;
    virtual void    PowerDown() = 0;

    // courtesy functions. inline by default.
    IOPort *     DataInPort(IOPort * p = NULL) { if (p != NULL) datain = p; return datain; }
    IOPort *     DataOutPort(IOPort *p = NULL) { if (p != NULL) dataout = p; return dataout; }
    IOPort *     SelectPort(IOPort *p = NULL) { if (p != NULL) select = p; return select; }
    IOPort *     ClockPort(IOPort *p = NULL) { if (p != NULL) clock = p; return clock; }

    void         ClockData(Signal s) { if (s == Signal::High) clock->SetPinHigh(); else clock->SetPinLow(); }

    uint8       ID() const { return id; }
    BusType Type() const { return type; }
    BusMode Mode() const { return mode; }

protected:
    uint8    id;     // could be SPI ID, I2C address, etc.
    BusType  type;
    BusMode  mode;

    IOPort *        dataout;    // sda, miso or mosi or tx or rx
    IOPort *        datain;     // sda, miso or mosi or tx or rx
    IOPort *        select;     // !CS
    IOPort *        clock;      // sck,

    RingBuff *      rxBuff;     // most communication busses can benefit
    RingBuff *      txBuff;     // from buffering, if resources allow.
};

//! @class SystemBus
//! @brief The base class for the system busses: Control, Address, and Data
//! Any MCU that is on the systembus has a handle to one of these objects
//! that manage the bus for the owning class.
enum class BusTermination : uint8 { Series, Parallel, Thevenin };
enum class BusRequestPriority : uint8 { Low, Normal, High, Interrupt, CPU };
class SystemBus
{
public:
    SystemBus(uint8 i, BusType t, BusMode m);
    virtual ~SystemBus() { }

    void            RequestToken(BusRequestPriority);

    inline uint8    ID() const { return id; }
    inline BusType  Type() const { return type; }
    inline BusMode  Mode() const { return mode; }
    inline bool     HaveToken() const { return bToken; }

protected:
    uint8    id;     // could be SPI ID, I2C address, etc.
    BusType  type;
    BusMode  mode;
    BusTermination  termination;    // how is the bus terminated?
    bool    bToken;

};

#endif	/* _MUNIX_Bus_H */

